///////////////////////////////////////////////////////////
//  DataXMLReader.cpp
//  Implementation of the Class DataXMLReader
//  Created on:      24-Aug-2013 2:37:30 PM
//  Original author: Jakkaphan Aiemcharoenjit
///////////////////////////////////////////////////////////

#include "DataXMLReader.h"
#include "DataSchemaXML.h"
#include "Item.h"
#include "Header.h"
#include "Pages.h"
#include "Page.h"
#include "BoolData.h"
#include "IntData.h"
#include "DoubleData.h"
#include "StringData.h"
#include "Choices.h"
#include <stdio.h>

using namespace Data;

DataXMLReader::DataXMLReader()
{

}

DataXMLReader::~DataXMLReader()
{

}

IPages* DataXMLReader::CreatePages( pugi::xml_node pagesNode )
{
  IPages* result = NULL;
  if(!_tcscmp(pagesNode.name(), DataSchemaXML::PAGES_ELEMENT.c_str()))
  {
    result = new Pages();

    // Attribute
    pugi::xml_attribute_iterator itAttr = pagesNode.attributes_begin();
    while(itAttr != pagesNode.attributes_end())
    {
      if(!_tcscmp(itAttr->name(), DataSchemaXML::NAME_ATTR.c_str()))
        result->SetName(itAttr->value());
      itAttr++;
    }

    //Element
    pugi::xml_node_iterator itNode = pagesNode.begin();
    while(itNode != pagesNode.end())
    {
      result->AppendPage(CreatePage(*itNode, result));
      itNode++;
    }
  }
  return result;
}

IData* DataXMLReader::CreateData( pugi::xml_node dataNode )
{
  IData* result = NULL;
  if(!_tcscmp(dataNode.name(), DataSchemaXML::BOOLDATA_ELEMENT.c_str()))
  {
    if(!_tcscmp(dataNode.child_value(), _T("TRUE")))
      result = new BoolData();
    else
      result = new BoolData(false);
  }
  else if(!_tcscmp(dataNode.name(), DataSchemaXML::INTDATA_ELEMENT.c_str()))
  {
    IInt* data = new IntData();
    data->SetValue(_ttol(dataNode.child_value()));
    
    result = data;
  }
  else if(!_tcscmp(dataNode.name(), DataSchemaXML::DOUBLEDATA_ELEMENT.c_str()))
  {
    IDouble* data = new DoubleData();
    data->SetValue(_ttod(dataNode.child_value()));
    result = data;
  }
  else if(!_tcscmp(dataNode.name(), DataSchemaXML::STRINGDATA_ELEMENT.c_str()))
  {
    IString* data = new StringData();
    data->SetValue(dataNode.child_value());
    result = data;
  }
  return result;
}

Item* DataXMLReader::CreateItem( pugi::xml_node itemNode, IObject* parent )
{
  Item* result = NULL;
  if(!_tcscmp(itemNode.name(), DataSchemaXML::ITEM_ELEMENT.c_str()))
  {
    result = new Item(_T(""), IData::NULL_T);
    
    // Set parent
    //result->SetParent(parent);

    // Attribute
    pugi::xml_attribute_iterator itAttr = itemNode.attributes_begin();
    while(itAttr != itemNode.attributes_end())
    {
      if(!_tcscmp(itAttr->name(), DataSchemaXML::NAME_ATTR.c_str()))
        result->SetName(itAttr->value());
      itAttr++;
    }

    // Element
    pugi::xml_node_iterator itNode = itemNode.begin();
    while(itNode != itemNode.end())
    {
      if(!_tcscmp(itNode->name(), DataSchemaXML::COMMENT_ELEMENT.c_str()))
        result->SetComment(itNode->child_value());
      else
        result->SetData(CreateData((*itNode)));
      itNode++;
    }
  }

  return result;
}

IHeader* DataXMLReader::CreateHeader( pugi::xml_node headerNode, IObject* parent )
{
  IHeader* result = NULL;
  if(!_tcscmp(headerNode.name(), DataSchemaXML::HEADER_ELEMENT.c_str()))
  {
    result = new Header();

    //Set parent
    //result->SetParent(parent);

    // Attribute
    pugi::xml_attribute_iterator itAttr = headerNode.attributes_begin();
    while(itAttr != headerNode.attributes_end())
    {
      if(!_tcscmp(itAttr->name(), DataSchemaXML::NAME_ATTR.c_str()))
        result->SetName(itAttr->value());
      itAttr++;
    }

    // Element
    pugi::xml_node_iterator itNode = headerNode.begin();
    while(itNode != headerNode.end())
    {
      if(!_tcscmp(itNode->name(), DataSchemaXML::ITEM_ELEMENT.c_str()))
        result->AppendChild(CreateItem(*itNode, result));
      else
        result->AppendChild(CreateHeader((*itNode), result));
      itNode++;
    }
  }
  return result;
}

IPage* DataXMLReader::CreatePage( pugi::xml_node pageNode , IObject* parent)
{
  IPage* result = NULL;
  if(!_tcscmp(pageNode.name(), DataSchemaXML::PAGE_ELEMENT.c_str()))
  {
    result = new Page(IPage::TEXTPAGE_T);

    // Set parent
    //result->SetParent(parent);

    // Attribute
    pugi::xml_attribute_iterator itAttr = pageNode.attributes_begin();
    while(itAttr != pageNode.attributes_end())
    {
      if(!_tcscmp(itAttr->name(), DataSchemaXML::NAME_ATTR.c_str()))
        result->SetName(itAttr->value());
      else if(!_tcscmp(itAttr->name(), DataSchemaXML::TEMPLATENAME_ATTR.c_str()))
        result->SetTemplateName(itAttr->value());
      else if(!_tcscmp(itAttr->name(), DataSchemaXML::PAGETYPE_ATTR.c_str()))
        result->SetPageType(itAttr->value());
      else if(!_tcscmp(itAttr->name(), DataSchemaXML::TEMPLATETIME_ATTR.c_str()))
        result->SetTemplateTime(itAttr->value());
      else if(!_tcscmp(itAttr->name(), DataSchemaXML::BUILDTIME_ATTR.c_str()))
        result->SetBuildTime(itAttr->value());

      itAttr++;
    }

    // Element
    pugi::xml_node_iterator itNode = pageNode.begin();
    while(itNode != pageNode.end())
    {
      if(!_tcscmp(itNode->name(), DataSchemaXML::COLLECTIONITEM_ELEMENT.c_str()))
      {
        pugi::xml_node_iterator collectionNode = itNode->begin();
        while(collectionNode != itNode->end())
        {
          if(!_tcscmp(collectionNode->name(), DataSchemaXML::ITEM_ELEMENT.c_str()))
            result->AppendChild(CreateItem(*collectionNode, result));
          else if(!_tcscmp(collectionNode->name(), DataSchemaXML::HEADER_ELEMENT.c_str()))
            result->AppendChild(CreateHeader(*collectionNode, result));
          collectionNode++;
        }
      }
      else if(!_tcscmp(itNode->name(), DataSchemaXML::CHOICES_ELEMENT.c_str()))
        result->SetChoices(CreateChoices((*itNode)));
      else if(!_tcscmp(itNode->name(), DataSchemaXML::TITLEPAGE_ELEMENT.c_str()))
        result->SetTitle(itNode->child_value());
      else if(!_tcscmp(itNode->name(), DataSchemaXML::COMMENT_ELEMENT.c_str()))
        result->SetComment(itNode->child_value());

      itNode++;
    }
  }
  return result;
}

IChoices* DataXMLReader::CreateChoices( pugi::xml_node choicesNode )
{
  IChoices* result = NULL;
  if(!_tcscmp(choicesNode.name(), DataSchemaXML::CHOICES_ELEMENT.c_str()))
  {
    result = new Choices();

    //Element
    pugi::xml_node_iterator itNode = choicesNode.begin();
    while(itNode != choicesNode.end())
    {
      result->AddChoice(itNode->child_value());
      itNode++;
    }
  }
  return result;
}
